using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace SWellPlate
{
	public class DataGridCellWell : Control
	{
		public static readonly DependencyProperty HighLightProperty = DependencyProperty.Register("HighLight", typeof(bool), typeof(DataGridCellWell), new PropertyMetadata(false, OnHighLightVisual));

		public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(DataGridCellWell), new PropertyMetadata(false, OnInvalidateVisual));

		public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(DataGridCellWell), new PropertyMetadata(string.Empty, OnInvalidateVisual));

		public static readonly DependencyProperty InvalidProperty = DependencyProperty.Register("Invalid", typeof(bool), typeof(DataGridCellWell), new PropertyMetadata(false, OnInvalidateVisual));

		private static SolidColorBrush brushSelected = new SolidColorBrush(Color.FromArgb(byte.MaxValue, 88, 88, 88));

		private static SolidColorBrush brushGroup = new SolidColorBrush(Color.FromArgb(byte.MaxValue, 196, 196, 196));

		private static Geometry geometryBackgroud = Geometry.Parse("M0.5,16.5 C0.5,7.663444 7.663444,0.5 16.5,0.5 L108.5,0.5 C117.33656,0.5 124.5,7.663444 124.5,16.5 L124.5,18.5 C124.5,27.336556 117.33656,34.5 108.5,34.5 L16.5,34.5 C7.663444,34.5 0.5,27.336556 0.5,18.5 z");

		private static BitmapImage shadowImage = new BitmapImage(new Uri("pack://application:,,,/SWellPlate;component/Resources/shadow.png", UriKind.RelativeOrAbsolute));

		private TransformGroup transformGroup = new TransformGroup();

		private ScaleTransform scaleTransform = new ScaleTransform();

		private TranslateTransform translateTransform = new TranslateTransform();

		public bool HighLight
		{
			get
			{
				return (bool)GetValue(HighLightProperty);
			}
			set
			{
				SetValue(HighLightProperty, value);
			}
		}

		public bool IsSelected
		{
			get
			{
				return (bool)GetValue(IsSelectedProperty);
			}
			set
			{
				SetValue(IsSelectedProperty, value);
			}
		}

		public string Text
		{
			get
			{
				return (string)GetValue(TextProperty);
			}
			set
			{
				SetValue(TextProperty, value);
			}
		}

		public bool Invalid
		{
			get
			{
				return (bool)GetValue(InvalidProperty);
			}
			set
			{
				SetValue(InvalidProperty, value);
			}
		}

		private static void OnHighLightVisual(object sender, DependencyPropertyChangedEventArgs args)
		{
			if (args.NewValue != args.OldValue && Mouse.LeftButton != MouseButtonState.Pressed)
			{
				DataGridCellWell dataGridCellWell = sender as DataGridCellWell;
				if (dataGridCellWell != null && (!(bool)args.NewValue || dataGridCellWell.IsSelected))
				{
					dataGridCellWell.InvalidateVisual();
				}
			}
		}

		private static void OnInvalidateVisual(object sender, DependencyPropertyChangedEventArgs args)
		{
			if (args.NewValue != args.OldValue)
			{
				DataGridCellWell dataGridCellWell = sender as DataGridCellWell;
				if (dataGridCellWell != null)
				{
					dataGridCellWell.InvalidateVisual();
				}
			}
		}

		public DataGridCellWell()
		{
			SetBinding(HighLightProperty, new Binding("IsMouseOver")
			{
				Mode = BindingMode.OneWay,
				RelativeSource = RelativeSource.Self
			});
			translateTransform.X = 2.0;
			translateTransform.Y = 2.0;
			transformGroup.Children.Add(scaleTransform);
			transformGroup.Children.Add(translateTransform);
		}

		protected override void OnRender(DrawingContext drawingContext)
		{
			Console.WriteLine(string.Format("OnRender:{0}, IsSelected:{1},HighLight:{2}", DateTime.Now.ToString(), IsSelected, HighLight));
			StreamGeometry streamGeometry = null;
			if (IsSelected)
			{
				streamGeometry = new StreamGeometry();
				using (StreamGeometryContext streamGeometryContext = streamGeometry.Open())
				{
					streamGeometryContext.BeginFigure(new Point(0.0, 0.0), true, false);
					streamGeometryContext.LineTo(new Point(base.ActualWidth, 0.0), true, false);
					streamGeometryContext.LineTo(new Point(base.ActualWidth, base.ActualHeight), true, false);
					streamGeometryContext.LineTo(new Point(0.0, base.ActualHeight), true, false);
					streamGeometryContext.LineTo(new Point(0.0, 0.0), true, false);
					streamGeometryContext.Close();
				}
				drawingContext.DrawGeometry(brushSelected, null, streamGeometry);
			}
			drawingContext.PushTransform(transformGroup);
			drawingContext.DrawGeometry(base.Background, new Pen(new SolidColorBrush(Color.FromArgb(byte.MaxValue, 88, 88, 88)), 1.0), geometryBackgroud);
			drawingContext.Pop();
			if (Invalid)
			{
				streamGeometry = new StreamGeometry();
				using (StreamGeometryContext streamGeometryContext2 = streamGeometry.Open())
				{
					streamGeometryContext2.BeginFigure(new Point(7.0, 4.0), true, false);
					streamGeometryContext2.LineTo(new Point(base.ActualWidth - 14.0, base.ActualHeight - 8.0), true, false);
					streamGeometryContext2.BeginFigure(new Point(7.0, base.ActualHeight - 8.0), true, false);
					streamGeometryContext2.LineTo(new Point(base.ActualWidth - 14.0, 4.0), true, false);
					streamGeometryContext2.Close();
				}
				drawingContext.DrawGeometry(null, new Pen(new SolidColorBrush(Color.FromArgb(byte.MaxValue, 244, 244, 245)), 3.0), streamGeometry);
			}
			if (!string.IsNullOrEmpty(Text))
			{
				Typeface typeface = new Typeface(base.FontFamily, FontStyles.Normal, (IsSelected && HighLight) ? FontWeights.Bold : FontWeights.Normal, FontStretches.Normal);
				FormattedText formattedText = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, base.FontSize, base.Foreground);
				drawingContext.DrawText(formattedText, new Point((base.ActualWidth - formattedText.Width) / 2.0, (base.ActualHeight - formattedText.Height) / 2.0));
			}
			if (IsSelected && HighLight)
			{
				drawingContext.DrawImage(shadowImage, new Rect(2.0, 2.0, base.ActualWidth - 2.0, base.ActualHeight - 2.0));
			}
		}

		protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
		{
			scaleTransform.ScaleX = (sizeInfo.NewSize.Width - translateTransform.X * 2.0) / (geometryBackgroud.Bounds.Width + geometryBackgroud.Bounds.Left * 2.0);
			scaleTransform.ScaleY = (sizeInfo.NewSize.Height - translateTransform.Y * 2.0) / (geometryBackgroud.Bounds.Height + geometryBackgroud.Bounds.Top * 2.0);
			base.OnRenderSizeChanged(sizeInfo);
		}
	}
}
